define([], function () {//the config must required before util
    var koTemplate = {
        helloWorld: '<div class="container bg-info" style="height: 1000px;"></div>',
        empty: '<div class="w-100 bg-primary border"></div>',
        emptyContent:{template:'<div class="text-center mt-1 mb-1" data-bind="css:_css"><img data-bind="attr:_imgAttr"/><p data-bind="style:{color:color}" class="mt-1">暂无内容</p></div>',params: {}},
        emptyCmp:{name:'cmp:Empty',params:undefined},
        emptyAjax:{success:true,message:'',totalCount:0,data:undefined}
    };

    var mainCol2Css = {
        col1: {
            'col-sm-12': true,
            'col-md-3': true,
            'col-lg-2': true
        },
        col2: {
            'col-sm-12': true,
            'col-md-9': true,
            'col-lg-10': true
        }
    };

    var route = {
        maxLevel: 2,//1-6
        order: ['','main', 'second', 'third', 'fourth', 'fifth', 'sixth']
    };

    var buttonCss = {
        primary: {
            btn: true,
            'btn-outline-primary': true,
            'btn-primary': false
        },
        secondary: {
            btn: true,
            'btn-outline-secondary': true,
            'btn-secondary': false
        }
    };

    return {
        //ajax
        crossDomain: false,
        baseUrl: '.',
        restPrefix: '/rest',
        ajaxComplete: undefined,//this prop config the global all back for ajax
        ajaxFormatter:undefined,
        //data
        modelDefaultId: 0,
        store:{
            formatter:undefined,
            pageNoName:'pageNo',
            pageSizeName:'pageSize',
            method:'Get',
            proxyType:'rest'
        },

        //ui
        copyright: 'Copyright 2018. 版权所有：吉思小哥小',
        operationType: 'icon',
        mainCol2Css: mainCol2Css,
        buttonCss: buttonCss,

        koTemplate: koTemplate,
        route: route
    }
});

//the class extend function
Function.prototype.defineMethod = function (methodName, methodBody) {
    this.prototype[methodName] = methodBody;
    methodBody.$name = methodName;
    this.$owner = this;
};

Function.prototype.extend = function (baseType) {
    var tempType = function () {
    };
    tempType.prototype = baseType.prototype;

    this.prototype = new tempType();
    this.prototype.constructor = this;
    this.prototype.callParent = function () {
        var method = arguments.callee.caller;

        return method.$owner.$baseType.prototype[method.$name].apply(this, arguments);
    };

    this.$baseType = baseType;
    this.defineMethod('constructor', this.prototype.constructor);
};
//Array extension
//remove a val or obj
Array.prototype.remove = function (val) {
    var index = -1;

    if (typeof val == 'object') {
        index = this.indexOfObject(val);
    } else {
        index = this.indexOf(val);
    }


    if (index > -1) {
     return this.splice(index, 1);
    }
};
//remove by index
Array.prototype.removeAt = function(index) {
    return this.splice(index,1);
}

Array.prototype.sortByField = function (/*{fieldName:,asc:}*/param) {
    if (param.fieldName) {
        this.sort(function (a, b) {
            if (typeof a[param.fieldName] == 'string') {
                return a[param.fieldName] > b[param.fieldName];
            } else {
                return a[param.fieldName] - b[param.fieldName];
            }
        });

        if (param.asc == false) {
            this.reverse();
        }
    }
};

Array.prototype.indexOfObject = function (obj) {
    for (var i = 0; i < this.length; ++i) {
        if (JSON.stringify(obj) == JSON.stringify(this[i])) {
            return i;
        }
    }
};
//return the first match item
Array.prototype.findItemByField = function (/*{value:,name:}*/params) {
    for (var i = 0; i < this.length; ++i) {
        if ((typeof this[i][params.name] == 'function'?this[i][params.name]():this[i][params.name]) == (typeof params.value == 'function'?params.value():params.value)) {
            return this[i];
        }
    }
};

Array.prototype.findItemsByField = function (/*{value:,name:}*/params) {
    var menus = [];

    this.forEach(function (menu) {
        if (menu[params.name] == params.value) {
            menus.push(menu);
        }
    });

    return menus;
};

//param obj
Array.prototype.pushItem = function (item) {
    if (item) {
        this.push(item);
    }
}

Array.prototype.findSubItemsByParentField = function (/*{value:,name:,pName:}*/params) {
    var item = this.findItemByField({value: params.value, name: params.name});
    var rtn = [];

    if (item) {
        rtn = this.findItemsByField({value: item.id, name: params.pName});
    }

    return rtn;
};
//return field value array
Array.prototype.mapByField = function (field) {
    var temp = [];

    this.forEach(function (obj) {
        temp.push(obj[field]);
    });

    return temp;
};
//return new array contain obj with fields param
Array.prototype.mapByFields = function (fields) {
    var temp = [];

    this.forEach(function (obj) {
        temp.push(JSON.exportJS(obj,fields));
    });

    return temp;
};
//factory
Array.factory = {
    initWithSame: function (/*{value:,count:}*/ params) {
        var rtn = [];

        if (params.count) {
            for (var i = 0; i < params.count; ++i) {
                rtn.push(params.value);
            }
        }

        return rtn;
    }
};
//string extension
String.prototype.firstCharacterU = function () {
    if (this.trim()) {
        return this.charAt(0).toUpperCase() + this.substr(1, this.length - 1);
    } else {
        return "";
    }
};

String.prototype.formatTpl = function () {
    //the tpl eg {0}:{1}:{2}
    var params = arguments;
    var tpl = this;

    if (tpl && arguments.length > 0) {
        if (typeof arguments[0] == 'object') params = arguments[0];

        for (var i = 0; i < params.length; ++i) {
            tpl = tpl.replace('{' + i + '}', params[i]);
        }
    }

    return tpl;
};

String.prototype.delHtmlTag = function() {
    return this.replace(/<[^>]+>/g,"");
};
//JSON extension
//==convert a json object to uri
JSON.js2Uri = function (obj) {
    return encodeURI(JSON.stringify(obj));
};
JSON.uri2JS = function (uri) {
    return JSON.parse(decodeURI(uri));
};
//==convert json to url query str
JSON.js2Search = function (obj) {
    try {
        var tempArr = [];
        for (var i in obj) {
            var key = encodeURIComponent(i);
            var value = encodeURIComponent(obj[i]);
            tempArr.push(key + '=' + value);
        }
        var urlParamsStr = tempArr.join('&');
        return urlParamsStr;
    } catch (err) {
        return '';
    }
};

JSON.search2JS = function (search) {
    var rtnObj = {};

    if(!search) search = window.location.search;

    if (search) {
        var splitStr = search.split('?')[1].split("&");
        for (var i = 0; i < splitStr.length; i++) {
            rtnObj[decodeURIComponent(splitStr[i].split("=")[0])] = decodeURIComponent(splitStr[i].split("=")[1]);
        }
    }

    return rtnObj;
};

JSON.jsEqual = function (js1, js2) {
    if (js1 == js2) return true;
    if (js1) js1 = JSON.stringify(js1);
    if (js2) js2 = JSON.stringify(js2);
    if (js1 == js2) return true;

    return false;
};
//==export fields from obj to a new obj.
JSON.exportJS = function(obj,/*['field_name',{from:'field_name',to:'field_name'}*/fields){
    var temp = {}

    if(obj&&fields){
        fields.forEach(function (field) {
            if(typeof field == 'string'){
                temp[field] = obj[field];
            }
            else {
                temp[field.to] = obj[field.from];
            }
        });
    }

    return temp;
};
//File extension
File.prototype.getExtension = function () {
    var extension = this.name.split('.')[1];

    return extension ? '.' + extension : '';
};
//date extension
/**
 * 对Date的扩展，将 Date 转化为指定格式的String
 * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符
 * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
 * eg:
 * (new Date()).pattern("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
 * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
 * (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
 * (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
 * (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
 */
Date.createInstance = function(str){
    if(!str){
        return 0;
    }

    var arr=str.split(" ");
    var d=arr[0].split("-");
    var t=arr[1].split(":");
    var date = new Date();

    date.setFullYear(d[0],d[1]-1,d[2]);
    date.setHours(t[0],t[1],t[2]);

    return date;
}

Date.prototype.pattern = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
        "H+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    var week = {
        "0": "日",
        "1": "一",
        "2": "二",
        "3": "三",
        "4": "四",
        "5": "五",
        "6": "六"
    };
    if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    }
    if (/(E+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "星期" : "周") : "") + week[this.getDay() + ""]);
    }
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        }
    }
    return fmt;
};
